package com.example.testmarkwon

import org.commonmark.node.AbstractVisitor
import org.commonmark.node.Node
import org.commonmark.node.Text

/**
 * 抽象语法树打印工具
 */
object AstPrinter {

    fun printAst(root: Node, sb: StringBuilder) {
        AstWalker().walk(root, 0, mutableListOf(), sb)
    }

    private class AstWalker : AbstractVisitor() {

        fun walk(node: Node?, depth: Int, isLastFlags: MutableList<Boolean>, sb: StringBuilder) {
            if (node == null) return

            // 生成当前节点的树形前缀
            val prefix = buildTreePrefix(depth, isLastFlags)
            // 生成节点类型描述
            val nodeInfo = buildNodeInfo(node)
            // 输出日志
            sb.appendLine(prefix + nodeInfo)

            // 处理子节点
            var child = node.firstChild
            val childFlags = ArrayList(isLastFlags)
            while (child != null) {
                val isLast = child.next == null
                childFlags.add(isLast)
                walk(child, depth + 1, childFlags, sb)
                childFlags.removeAt(childFlags.size - 1)
                child = child.next
            }
        }

        private fun buildTreePrefix(depth: Int, isLastFlags: List<Boolean>): String {
            return buildString {
                for (i in 0 until depth) {
                    if (i > 0) {
                        append(if (isLastFlags[i - 1]) "   " else "│  ")
                    }
                    if (i == depth - 1) {
                        append(if (isLastFlags[i]) "└─ " else "├─ ")
                    }
                }
            }
        }

        private fun buildNodeInfo(node: Node): String {
            // 提取类名（去掉包路径）
            val className = node::class.simpleName ?: "UnknownNode"
            // 提取文本内容（如果是 Text 节点）
            val textContent = if (node is Text) " (Text: \"${node.literal}\")" else ""
            return "$className$textContent"
        }
    }
}